<html>

<head>
    <title>Multi-rotor motor mixing calculator</title>
    <meta http-equiv="content-type" content="application/xhtml; charset=UTF-8" />
    <!-- <script type="text/javascript" src="js/jquery-1.11.3.min.js"></script> -->
    <script type="text/javascript" src="js/jquery-3.6.0.min.js"></script>
    <script type="text/javascript" src="js/mixercalc.js"></script>
    <link type="text/css" rel="stylesheet" href="css/mixercalc.css" />
</head>

<body>
    <h3>Motor mixing calculator, by @iforce2d</h3>
    <br>
    <div style="width:950px; "> This tool lets you calculate mixer settings by simply measuring the distances between motors. It is intended for "flat" motor layouts. i.e. this will not work for X8, Y6, Z, Lynchpin, etc.  True-X do not gernerally need calculation.  Stretch-X, Squish-X, DeadCat, H, etc. should benefit from calculations.<br>
        <br> For keyboard input, first click the graphical canvas to give it focus. Then you can use these keys: <ul style="margin-left:32px">
            <li>left arrow -- add a CCW motor at the mouse position</li>
            <li>right arrow -- add a CW motor at the mouse position</li>
            <li>r or up-arrow -- reverse the rotation of the highlighted motor</li>
            <li>d or delete -- delete the mouse-overed motor</li>
        </ul>
        <br>
        After adding the necessary motors on the canvas, enter constraints for pairs of motors, and let the simulation run for a few seconds until the output values at the bottom of the page have settled.<br>
        <br>
        Ideally each motor should have <b><i>three constraints</i></b>. When three or more constraints are present the inner circle for that motor will turn green. Make sure to have at least one horizontal or vertical constraint to define the overall direction of the layout.<br>
        <br> For a demonstration of usage, see: <a href="https://www.youtube.com/watch?v=9FvpT9jH0NA" target="_blank">this YouTube video</a>. </div>
    <br>
    <div>
        <canvas id="mixerviz" tabindex="1" width="600" height="600"></canvas>
        <div id="mixervals">
            <div> Constraints<br>
                <div>
                    <textarea id="inputs" style="float:left; height: 200px;"></textarea>
                    <div style="display:inline-block;margin-left:15px"> Examples <br> 4 motors:<br>
                        <ul style="margin-left:32px">
                            <li><a href="index.html#" class="preset" id="quadx">Quad X</a></li>
                            <li><a href="index.html#" class="preset" id="quad+">Quad +</a></li>
                            <!--<li><a href="index.html#" class="preset" id="apex5">Apex 5"</a></li>-->
                            <li><a href="index.html#" class="preset" id="clone6">Clone 6"</a></li>
                            <li><a href="index.html#" class="preset" id="zmr">ZMR250</a></li>
                            <li><a href="index.html#" class="preset" id="gh160">Diatone Grasshopper 160</a></li>
                        </ul> 6 motors:<br>
                        <ul style="margin-left:32px">
                            <li><a href="index.html#" class="preset" id="hexx">Hex X</a></li>
                        </ul> 8 motors:<br>
                        <ul style="margin-left:32px">
                            <li><a href="index.html#" class="preset" id="octx">Octo X</a></li>
                            <li><a href="index.html#" class="preset" id="jure">Jure custom</a></li>
                        </ul>
                    </div>
                </div>
            </div>
            <div style="float:left">
                <br> Enter lines in the format:<br>
                <b>[<i>motor</i>] [<i>motor</i>] [<i>constraint</i>]</b><br>
                <br> A constraint can be one of:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b><i>[number]<i></b> - distance between locations<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b><i>h<i></b> - align motors horizontally<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b><i>v<i></b> - align motors vertically<br>
                <br> Examples:<br> Motors 1 and 2 are 195mm apart<br>
                <b>1 2 195</b> <br> Motors 3 and 4 are 220mm apart<br>
                <b>4 3 220</b> <br> Motors 2 and 4 are aligned horizontally<br>
                <b>2 4 h</b> <br> Motors 1 and 2 are aligned vertically<br>
                <b>2 1 v</b> <br>
                <br> Constraints will be automatically applied two seconds after the last change has been made. If the motors get into any strange positions you can move them manually by dragging with the mouse. </div>
        </div>
    </div>
    <br>
    <br>
    <h4>Mixer commands (<span style="color: red;">Warning: potentially unsafe until all motors constrained to green status in graphical canvas above.  Pilot is responsible for correct propeller directions. There are no software checks.</span>)</h4>
    <br>
    <div>
        <div style="width:640px;float:left">
            <!-- <select id="commandtype" onchange="onCommandTypeChanged()"> -->
                <!-- <option value="selectone">Select command type</option> -->
                <!-- <option value="cf1.10">Cleanflight from 1.10 onwards</option> -->
            <!-- </select><br><br> -->
            <pre id="commands" class="outputpanel"></pre>
            Moving the mouse over the area below will pause updates to let you copy the text.<br>
            <br>
            <!--<span id="cfextra" style="display:none;color:red">Remember to also execute 'save' to keep the mixer settings!</span>-->
            <!--<span id="arducopterextra" style="display:none">See AP_MotorsMatrix::setup_motors() in <a href="https://github.com/ArduPilot/ardupilot/blob/master/libraries/AP_Motors/AP_MotorsMatrix.cpp#L466">libraries/AP_Motors/AP_MotorsMatrix.cpp</a></span><br>-->
        </div>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
</body>

</html>
